﻿using System;
using System.Collections.Generic;
using System.Text;

namespace RedBlueBalls
{
    /// <summary>
    /// Compare the same red balls with current record and the past records
    /// </summary>
    class RedSame
    {
        private static bool analyzed = false;
        private static bool checkBest = false;
        private const int ROUND = 50;
        private const int BEST_KEY = 2;
        private const int MAX_KEY = 4;
        private static RedBlueBallRecord[] lastRecords = null;
        private static int size = 0;
        private static GapAnalyzer[] analyzers = new GapAnalyzer[ROUND];

        public static void analyze(RedBlueBallRecord[] records)
        {
            lastRecords = records;
            size = lastRecords.Length;

            if (checkBest)
            {
                StringBuilder sb = new StringBuilder();

                for (int gap = 0; gap < ROUND; gap++)
                {
                    analyzers[gap] = new GapAnalyzer(gap + 1, records);
                    sb.AppendLine(analyzers[gap].ToString());
                }

                Tracer.AppendMessage(sb.ToString());
            }

            analyzed = true;
        }

        public static bool predict(RedBlueBallRecord candidate)
        {
            if (!analyzed)
            {
                Tracer.AppendMessage("Please analyze the data first!");
                return false;
            }

            for (int i = 0; i < size; i++)
            {
                int same = lastRecords[size - 1 - i].CountSameReds(candidate);
                if (i < ROUND && same > BEST_KEY)
                    return false;
                else if (same > MAX_KEY)
                    return false;
            }

            return true;
        }

        /// <summary>
        /// Analyze the same red ball by gap
        /// </summary>
        private class GapAnalyzer
        {
            private int gap;
            private List<int> list;
            private int index;
            private int key;

            public GapAnalyzer(int gap, RedBlueBallRecord[] records)
            {
                this.gap = gap;
                list = new List<int>();
                for (int i = records.Length - 1; i >= gap; i--)
                {
                    int same = records[i].CountSameReds(records[i - gap]);
                    Util.Add(list, same);
                }
                index = list.Count / 10;
                key = list[index];
            }

            public int Gap
            {
                get { return gap; }
            }

            public int Key
            {
                get { return key; }
            }

            public override string ToString()
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("Gap ");
                sb.Append(gap.ToString("D2"));
                sb.Append(": ");
                for (int i = 0; i < index; i++)
                {
                    sb.Append(list[i].ToString("D1")).Append(' ');
                }

                return sb.ToString();
            }

            private void add(int number)
            {
                int count = list.Count;

                if (count == 0)
                {
                    list.Add(number);
                }
                else
                {
                    for (int i = 0; i < count; i++)
                    {
                        if (list[i] < number)
                        {
                            list.Insert(i, number);
                            return;
                        }
                    }

                    // The last one
                    list.Add(number);
                }
            }
        }
    }
}
